package com.wffz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wffz.dto.BetDTO;
import com.wffz.dto.BetOnDTO;
import com.wffz.mapper.BetMapper;
import com.wffz.mapper.ClientUserMapper;
import com.wffz.mapper.IncomeLogMapper;
import com.wffz.po.*;
import com.wffz.service.BetService;
import com.wffz.service.UserService;
import com.wffz.service.WffzConfigService;
import jodd.cli.Cli;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author sunlei
 * @className BetServiceImpl
 * @Description
 * @date 2023-02-18 16:10
 **/
@Service
@Slf4j
public class BetServiceImpl implements BetService {

    @Resource
    private BetMapper betMapper;

    @Resource
    private UserService userService;

    @Resource
    private IncomeLogMapper incomeLogMapper;

    @Resource
    private WffzConfigService configService;

    @Autowired
    private RedisTemplate<String, ? extends Object> redisTemplate;

    @Override
    public boolean saveBet(Bet bet) {
        return betMapper.insert(bet) > 0;
    }

    @Override
    public boolean updateBet(Bet bet) {
        ClientUser c = userService.findUserByUserName(bet.getLoginName());
        float amount = bet.getWinAmount();
        c.setBalance(c.getBalance() + amount);
        userService.updateClientUser(c);
        //
        IncomeLog incomeLog = new IncomeLog();
        incomeLog.setUserId(c.getId());
        incomeLog.setLoginName(c.getLoginName());
        incomeLog.setAmount(amount);
        incomeLog.setCreateTime(new Date());
        incomeLog.setIncomeType("1");
        incomeLogMapper.insert(incomeLog);
        return betMapper.updateById(bet) > 0;
    }

    @Override
    public ClientUser update(Bet bet) {
        ClientUser c = userService.findUserByUserName(bet.getLoginName());
        float amount = bet.getWinAmount();
        c.setBalance(c.getBalance() + amount);
        userService.updateClientUser(c);
        //
        IncomeLog incomeLog = new IncomeLog();
        incomeLog.setUserId(c.getId());
        incomeLog.setLoginName(c.getLoginName());
        incomeLog.setAmount(amount);
        incomeLog.setCreateTime(new Date());
        incomeLog.setIncomeType("1");
        incomeLogMapper.insert(incomeLog);
        return c;
    }

    @Override
    @Transactional
    public Bet saveBetLJ(BetDTO dto, ClientUser clientUser) {
        String key = "brokerage";
        WffzConfig config = configService.getConfigByKey(key);
        float brokerage = Float.parseFloat(config.getConfigValue());
        // 新增下注信息
        Bet bet = new Bet();
        bet.setUserId(clientUser.getId());
        bet.setLoginName(clientUser.getLoginName());
        bet.setPeriodCode(dto.getPeriodCode());
        bet.setBetColor(dto.getBetColor());
        bet.setBetCost(dto.getBetCost());
        bet.setCreateTime(new Date());
        bet.setPatchType(dto.getPatchType());
        bet.setCreateBy(clientUser.getLoginName());
        bet.setBetNumber(dto.getBetNumber());
        bet.setBetType(dto.getBetType());
        betMapper.insert(bet);
        // 余额
        float balance = clientUser.getBalance() == null ? 0 : clientUser.getBalance();
        // 扣除费用，先扣除可以提现金额
        if (balance < bet.getBetCost()) {
            float surplusBalance = bet.getBetCost() - balance;
            clientUser.setBalance(0f);
            clientUser.setAwayBalance(clientUser.getAwayBalance() - surplusBalance);
        } else {
            clientUser.setBalance(balance - bet.getBetCost());
        }
        userService.updateClientUser(clientUser);
        // 给上级返点
        // 获取上级用户
        ClientUser parentUser = userService.findUserByinvitationCode(clientUser.getRcode());
        ClientUser pparentUser = null;
        ClientUser ppparentUser = null;
        // 给上级用户分成
        // 购买金额
        float betCost = dto.getBetCost();
        // 分成金额
        float fcje = 0f;
        if (parentUser != null) {
            fcje = betCost * brokerage * 0.45f;
            parentUser.setBalance(parentUser.getBalance() + fcje);
            userService.updateClientUser(parentUser);
            //
            pparentUser = userService.findUserByinvitationCode(parentUser.getRcode());
            // 收入支出日志
            IncomeLog incomeLog = new IncomeLog();
            incomeLog.setUserId(parentUser.getId());
            incomeLog.setLoginName(parentUser.getLoginName());
            incomeLog.setAmount(fcje);
            incomeLog.setCreateTime(new Date());
            incomeLog.setIncomeType("3");
            incomeLogMapper.insert(incomeLog);
        }

        if (pparentUser != null) {
            fcje = betCost * brokerage * 0.20f;
            pparentUser.setBalance(pparentUser.getBalance() + fcje);
            userService.updateClientUser(pparentUser);
            //
            ppparentUser = userService.findUserByinvitationCode(pparentUser.getRcode());
            // 收入支出日志
            IncomeLog incomeLog = new IncomeLog();
            incomeLog.setUserId(pparentUser.getId());
            incomeLog.setLoginName(pparentUser.getLoginName());
            incomeLog.setAmount(fcje);
            incomeLog.setCreateTime(new Date());
            incomeLog.setIncomeType("3");
            incomeLogMapper.insert(incomeLog);
        }

        if (ppparentUser != null) {
            fcje = betCost * brokerage * 0.10f;
            ppparentUser.setBalance(ppparentUser.getBalance() + fcje);
            userService.updateClientUser(ppparentUser);
            // 收入支出日志
            IncomeLog incomeLog = new IncomeLog();
            incomeLog.setUserId(ppparentUser.getId());
            incomeLog.setLoginName(ppparentUser.getLoginName());
            incomeLog.setAmount(fcje);
            incomeLog.setCreateTime(new Date());
            incomeLog.setIncomeType("3");
            incomeLogMapper.insert(incomeLog);
        }

        // 收入支出日志
        IncomeLog incomeLog = new IncomeLog();
        incomeLog.setUserId(clientUser.getId());
        incomeLog.setLoginName(clientUser.getLoginName());
        incomeLog.setAmount(bet.getBetCost());
        incomeLog.setCreateTime(new Date());
        incomeLog.setIncomeType("0");
        incomeLogMapper.insert(incomeLog);
        return bet;
    }

    @Override
    public List<Bet> getBetGroupColor(String periodCode, String patchType) {
        QueryWrapper<Bet> wrapper = new QueryWrapper<>();
        wrapper.select("sum(bet_cost) as betCost,bet_color");
        wrapper.eq("period_code", periodCode);
        wrapper.eq("patch_type", patchType);
        wrapper.groupBy("bet_color");
        List<Bet> list = betMapper.selectList(wrapper);
        Collections.sort(list);
        return list;
    }

    @Override
    public List<Bet> queryOrderList(Integer showType, ClientUser clientUser) {
        QueryWrapper<Bet> wrapper = new QueryWrapper<>();
        if (showType == 2) {
            //myOrder
            wrapper.eq("login_name", clientUser.getLoginName());
        } else if (showType == 1) {
            wrapper.isNotNull("win_amount").gt("win_amount", 0);
        }
        wrapper.orderByDesc("create_time");
        wrapper.last("limit 0 , 20");
        List<Bet> list = betMapper.selectList(wrapper);
        return list;
    }
}
